home *** CD-ROM | disk | FTP | other *** search
/ PC Advisor 2011 May / PC Advisor 190 E.iso / pc / ESSENTIALS / VLC Media Player 1.1 / vlc-1.1.5-win32.exe / sdk / include / vlc / plugins / vlc_threads.h < prev    next >
Encoding:
C/C++ Source or Header  |  2010-11-13  |  13.6 KB  |  444 lines

  1. /*****************************************************************************
  2.  * vlc_threads.h : threads implementation for the VideoLAN client
  3.  * This header provides portable declarations for mutexes & conditions
  4.  *****************************************************************************
  5.  * Copyright (C) 1999, 2002 the VideoLAN team
  6.  * Copyright ┬⌐ 2007-2008 R├⌐mi Denis-Courmont
  7.  *
  8.  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  9.  *          Samuel Hocevar <sam@via.ecp.fr>
  10.  *          Gildas Bazin <gbazin@netcourrier.com>
  11.  *          Christophe Massiot <massiot@via.ecp.fr>
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27.  
  28. #ifndef VLC_THREADS_H_
  29. #define VLC_THREADS_H_
  30.  
  31. /**
  32.  * \file
  33.  * This file defines structures and functions for handling threads in vlc
  34.  *
  35.  */
  36.  
  37. #if defined( UNDER_CE )
  38. #elif defined( WIN32 )
  39. #   include <process.h>                                         /* Win32 API */
  40.  
  41. #else                                         /* pthreads (like Linux & BSD) */
  42. #   define LIBVLC_USE_PTHREAD 1
  43. #   define LIBVLC_USE_PTHREAD_CANCEL 1
  44. #   define _APPLE_C_SOURCE    1 /* Proper pthread semantics on OSX */
  45.  
  46. #   include <unistd.h> /* _POSIX_SPIN_LOCKS */
  47. #   include <pthread.h>
  48. #   include <semaphore.h>
  49.  
  50. #endif
  51.  
  52. /*****************************************************************************
  53.  * Constants
  54.  *****************************************************************************/
  55.  
  56. /* Thread priorities */
  57. #ifdef __APPLE__
  58. #   define VLC_THREAD_PRIORITY_LOW      0
  59. #   define VLC_THREAD_PRIORITY_INPUT   22
  60. #   define VLC_THREAD_PRIORITY_AUDIO   22
  61. #   define VLC_THREAD_PRIORITY_VIDEO    0
  62. #   define VLC_THREAD_PRIORITY_OUTPUT  22
  63. #   define VLC_THREAD_PRIORITY_HIGHEST 22
  64.  
  65. #elif defined(LIBVLC_USE_PTHREAD)
  66. #   define VLC_THREAD_PRIORITY_LOW      0
  67. #   define VLC_THREAD_PRIORITY_INPUT   10
  68. #   define VLC_THREAD_PRIORITY_AUDIO    5
  69. #   define VLC_THREAD_PRIORITY_VIDEO    0
  70. #   define VLC_THREAD_PRIORITY_OUTPUT  15
  71. #   define VLC_THREAD_PRIORITY_HIGHEST 20
  72.  
  73. #elif defined(WIN32) || defined(UNDER_CE)
  74. /* Define different priorities for WinNT/2K/XP and Win9x/Me */
  75. #   define VLC_THREAD_PRIORITY_LOW 0
  76. #   define VLC_THREAD_PRIORITY_INPUT \
  77.         THREAD_PRIORITY_ABOVE_NORMAL
  78. #   define VLC_THREAD_PRIORITY_AUDIO \
  79.         THREAD_PRIORITY_HIGHEST
  80. #   define VLC_THREAD_PRIORITY_VIDEO 0
  81. #   define VLC_THREAD_PRIORITY_OUTPUT \
  82.         THREAD_PRIORITY_ABOVE_NORMAL
  83. #   define VLC_THREAD_PRIORITY_HIGHEST \
  84.         THREAD_PRIORITY_TIME_CRITICAL
  85.  
  86. #else
  87. #   define VLC_THREAD_PRIORITY_LOW 0
  88. #   define VLC_THREAD_PRIORITY_INPUT 0
  89. #   define VLC_THREAD_PRIORITY_AUDIO 0
  90. #   define VLC_THREAD_PRIORITY_VIDEO 0
  91. #   define VLC_THREAD_PRIORITY_OUTPUT 0
  92. #   define VLC_THREAD_PRIORITY_HIGHEST 0
  93.  
  94. #endif
  95.  
  96. /*****************************************************************************
  97.  * Type definitions
  98.  *****************************************************************************/
  99.  
  100. #if defined (LIBVLC_USE_PTHREAD)
  101. typedef pthread_t       vlc_thread_t;
  102. typedef pthread_mutex_t vlc_mutex_t;
  103. #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
  104. typedef pthread_cond_t  vlc_cond_t;
  105. #define VLC_STATIC_COND  PTHREAD_COND_INITIALIZER
  106. typedef sem_t           vlc_sem_t;
  107. typedef pthread_rwlock_t vlc_rwlock_t;
  108. typedef pthread_key_t   vlc_threadvar_t;
  109. typedef struct vlc_timer *vlc_timer_t;
  110.  
  111. #elif defined( WIN32 )
  112. #if !defined( UNDER_CE )
  113. typedef HANDLE vlc_thread_t;
  114. #else
  115. typedef struct
  116. {
  117.     HANDLE handle;
  118.     HANDLE cancel_event;
  119. } *vlc_thread_t;
  120. #endif
  121.  
  122. typedef struct
  123. {
  124.     bool dynamic;
  125.     union
  126.     {
  127.         struct
  128.         {
  129.             bool locked;
  130.             unsigned long contention;
  131.         };
  132.         CRITICAL_SECTION mutex;
  133.     };
  134. } vlc_mutex_t;
  135. #define VLC_STATIC_MUTEX { false, { { false, 0 } } }
  136.  
  137. typedef struct
  138. {
  139.     HANDLE   handle;
  140.     unsigned clock;
  141. } vlc_cond_t;
  142.  
  143. typedef HANDLE  vlc_sem_t;
  144.  
  145. typedef struct
  146. {
  147.     vlc_mutex_t   mutex;
  148.     vlc_cond_t    read_wait;
  149.     vlc_cond_t    write_wait;
  150.     unsigned long readers;
  151.     unsigned long writers;
  152.     DWORD         writer;
  153. } vlc_rwlock_t;
  154.  
  155. typedef DWORD   vlc_threadvar_t;
  156. typedef struct vlc_timer *vlc_timer_t;
  157. #endif
  158.  
  159. #if defined( WIN32 ) && !defined ETIMEDOUT
  160. #  define ETIMEDOUT 10060 /* This is the value in winsock.h. */
  161. #endif
  162.  
  163. /*****************************************************************************
  164.  * Function definitions
  165.  *****************************************************************************/
  166. VLC_EXPORT( void, vlc_mutex_init,    ( vlc_mutex_t * ) );
  167. VLC_EXPORT( void, vlc_mutex_init_recursive, ( vlc_mutex_t * ) );
  168. VLC_EXPORT( void, vlc_mutex_destroy, ( vlc_mutex_t * ) );
  169. VLC_EXPORT( void, vlc_mutex_lock, ( vlc_mutex_t * ) );
  170. VLC_EXPORT( int,  vlc_mutex_trylock, ( vlc_mutex_t * ) LIBVLC_USED );
  171. VLC_EXPORT( void, vlc_mutex_unlock, ( vlc_mutex_t * ) );
  172. VLC_EXPORT( void, vlc_cond_init,     ( vlc_cond_t * ) );
  173. VLC_EXPORT( void, vlc_cond_init_daytime, ( vlc_cond_t * ) );
  174. VLC_EXPORT( void, vlc_cond_destroy,  ( vlc_cond_t * ) );
  175. VLC_EXPORT( void, vlc_cond_signal, (vlc_cond_t *) );
  176. VLC_EXPORT( void, vlc_cond_broadcast, (vlc_cond_t *) );
  177. VLC_EXPORT( void, vlc_cond_wait, (vlc_cond_t *, vlc_mutex_t *) );
  178. VLC_EXPORT( int,  vlc_cond_timedwait, (vlc_cond_t *, vlc_mutex_t *, mtime_t) );
  179. VLC_EXPORT( void, vlc_sem_init, (vlc_sem_t *, unsigned) );
  180. VLC_EXPORT( void, vlc_sem_destroy, (vlc_sem_t *) );
  181. VLC_EXPORT( int,  vlc_sem_post, (vlc_sem_t *) );
  182. VLC_EXPORT( void, vlc_sem_wait, (vlc_sem_t *) );
  183.  
  184. VLC_EXPORT( void, vlc_rwlock_init, (vlc_rwlock_t *) );
  185. VLC_EXPORT( void, vlc_rwlock_destroy, (vlc_rwlock_t *) );
  186. VLC_EXPORT( void, vlc_rwlock_rdlock, (vlc_rwlock_t *) );
  187. VLC_EXPORT( void, vlc_rwlock_wrlock, (vlc_rwlock_t *) );
  188. VLC_EXPORT( void, vlc_rwlock_unlock, (vlc_rwlock_t *) );
  189. VLC_EXPORT( int, vlc_threadvar_create, (vlc_threadvar_t * , void (*) (void *) ) );
  190. VLC_EXPORT( void, vlc_threadvar_delete, (vlc_threadvar_t *) );
  191. VLC_EXPORT( int, vlc_threadvar_set, (vlc_threadvar_t, void *) );
  192. VLC_EXPORT( void *, vlc_threadvar_get, (vlc_threadvar_t) );
  193. VLC_EXPORT( int,  vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( vlc_object_t * ), int ) LIBVLC_USED );
  194. VLC_EXPORT( int,  vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) );
  195. VLC_EXPORT( void, vlc_thread_join,   ( vlc_object_t * ) );
  196.  
  197. VLC_EXPORT( int, vlc_clone, (vlc_thread_t *, void * (*) (void *), void *, int) LIBVLC_USED );
  198. VLC_EXPORT( void, vlc_cancel, (vlc_thread_t) );
  199. VLC_EXPORT( void, vlc_join, (vlc_thread_t, void **) );
  200. VLC_EXPORT (void, vlc_control_cancel, (int cmd, ...));
  201.  
  202. VLC_EXPORT( int, vlc_timer_create, (vlc_timer_t *, void (*) (void *), void *) LIBVLC_USED );
  203. VLC_EXPORT( void, vlc_timer_destroy, (vlc_timer_t) );
  204. VLC_EXPORT( void, vlc_timer_schedule, (vlc_timer_t, bool, mtime_t, mtime_t) );
  205. VLC_EXPORT( unsigned, vlc_timer_getoverrun, (vlc_timer_t) LIBVLC_USED );
  206.  
  207. #ifndef LIBVLC_USE_PTHREAD_CANCEL
  208. enum {
  209.     VLC_CLEANUP_PUSH,
  210.     VLC_CLEANUP_POP,
  211. };
  212. #endif
  213.  
  214. VLC_EXPORT( int, vlc_savecancel, (void) );
  215. VLC_EXPORT( void, vlc_restorecancel, (int state) );
  216. VLC_EXPORT( void, vlc_testcancel, (void) );
  217.  
  218. #if defined (LIBVLC_USE_PTHREAD_CANCEL)
  219. /**
  220.  * Registers a new procedure to run if the thread is cancelled (or otherwise
  221.  * exits prematurely). Any call to vlc_cleanup_push() <b>must</b> paired with a
  222.  * call to either vlc_cleanup_pop() or vlc_cleanup_run(). Branching into or out
  223.  * of the block between these two function calls is not allowed (read: it will
  224.  * likely crash the whole process). If multiple procedures are registered,
  225.  * they are handled in last-in first-out order.
  226.  *
  227.  * @param routine procedure to call if the thread ends
  228.  * @param arg argument for the procedure
  229.  */
  230. # define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)
  231.  
  232. /**
  233.  * Removes a cleanup procedure that was previously registered with
  234.  * vlc_cleanup_push().
  235.  */
  236. # define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
  237.  
  238. /**
  239.  * Removes a cleanup procedure that was previously registered with
  240.  * vlc_cleanup_push(), and executes it.
  241.  */
  242. # define vlc_cleanup_run( ) pthread_cleanup_pop (1)
  243. #else
  244. typedef struct vlc_cleanup_t vlc_cleanup_t;
  245.  
  246. struct vlc_cleanup_t
  247. {
  248.     vlc_cleanup_t *next;
  249.     void         (*proc) (void *);
  250.     void          *data;
  251. };
  252.  
  253. /* This macros opens a code block on purpose. This is needed for multiple
  254.  * calls within a single function. This also prevent Win32 developers from
  255.  * writing code that would break on POSIX (POSIX opens a block as well). */
  256. # define vlc_cleanup_push( routine, arg ) \
  257.     do { \
  258.         vlc_cleanup_t vlc_cleanup_data = { NULL, routine, arg, }; \
  259.         vlc_control_cancel (VLC_CLEANUP_PUSH, &vlc_cleanup_data)
  260.  
  261. # define vlc_cleanup_pop( ) \
  262.         vlc_control_cancel (VLC_CLEANUP_POP); \
  263.     } while (0)
  264.  
  265. # define vlc_cleanup_run( ) \
  266.         vlc_control_cancel (VLC_CLEANUP_POP); \
  267.         vlc_cleanup_data.proc (vlc_cleanup_data.data); \
  268.     } while (0)
  269.  
  270. #endif /* LIBVLC_USE_PTHREAD_CANCEL */
  271.  
  272. static inline void vlc_cleanup_lock (void *lock)
  273. {
  274.     vlc_mutex_unlock ((vlc_mutex_t *)lock);
  275. }
  276. #define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
  277.  
  278. # if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
  279. typedef pthread_spinlock_t vlc_spinlock_t;
  280.  
  281. /**
  282.  * Initializes a spinlock.
  283.  */
  284. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  285. {
  286.     if (pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE))
  287.         abort ();
  288. }
  289.  
  290. /**
  291.  * Acquires a spinlock.
  292.  */
  293. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  294. {
  295.     pthread_spin_lock (spin);
  296. }
  297.  
  298. /**
  299.  * Releases a spinlock.
  300.  */
  301. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  302. {
  303.     pthread_spin_unlock (spin);
  304. }
  305.  
  306. /**
  307.  * Deinitializes a spinlock.
  308.  */
  309. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  310. {
  311.     pthread_spin_destroy (spin);
  312. }
  313.  
  314. #elif defined (WIN32) && !defined (UNDER_CE)
  315.  
  316. typedef CRITICAL_SECTION vlc_spinlock_t;
  317.  
  318. /**
  319.  * Initializes a spinlock.
  320.  */
  321. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  322. {
  323.     if (!InitializeCriticalSectionAndSpinCount(spin, 4000))
  324.         abort ();
  325. }
  326.  
  327. /**
  328.  * Acquires a spinlock.
  329.  */
  330. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  331. {
  332.     EnterCriticalSection(spin);
  333. }
  334.  
  335. /**
  336.  * Releases a spinlock.
  337.  */
  338. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  339. {
  340.     LeaveCriticalSection(spin);
  341. }
  342.  
  343. /**
  344.  * Deinitializes a spinlock.
  345.  */
  346. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  347. {
  348.     DeleteCriticalSection(spin);
  349. }
  350.  
  351. #else
  352.  
  353. /* Fallback to plain mutexes if spinlocks are not available */
  354. typedef vlc_mutex_t vlc_spinlock_t;
  355.  
  356. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  357. {
  358.     vlc_mutex_init (spin);
  359. }
  360.  
  361. # define vlc_spin_lock    vlc_mutex_lock
  362. # define vlc_spin_unlock  vlc_mutex_unlock
  363. # define vlc_spin_destroy vlc_mutex_destroy
  364. #endif
  365.  
  366. /**
  367.  * Issues a full memory barrier.
  368.  */
  369. #if defined (__APPLE__)
  370. # include <libkern/OSAtomic.h> /* OSMemoryBarrier() */
  371. #endif
  372. static inline void barrier (void)
  373. {
  374. #if defined (__GNUC__) && !defined (__APPLE__) && \
  375.             ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
  376.     __sync_synchronize ();
  377. #elif defined(__APPLE__)
  378.     OSMemoryBarrier ();
  379. #elif defined(__powerpc__)
  380.     asm volatile ("sync":::"memory");
  381. #elif 0 // defined(__i386__) /*  Requires SSE2 support */
  382.     asm volatile ("mfence":::"memory");
  383. #else
  384.     vlc_spinlock_t spin;
  385.     vlc_spin_init (&spin);
  386.     vlc_spin_lock (&spin);
  387.     vlc_spin_unlock (&spin);
  388.     vlc_spin_destroy (&spin);
  389. #endif
  390. }
  391.  
  392. /*****************************************************************************
  393.  * vlc_thread_create: create a thread
  394.  *****************************************************************************/
  395. #define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY )         \
  396.     vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, FUNC, PRIORITY )
  397.  
  398. /*****************************************************************************
  399.  * vlc_thread_set_priority: set the priority of the calling thread
  400.  *****************************************************************************/
  401. #define vlc_thread_set_priority( P_THIS, PRIORITY )                         \
  402.     vlc_thread_set_priority( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PRIORITY )
  403.  
  404. /*****************************************************************************
  405.  * vlc_thread_join: wait until a thread exits
  406.  *****************************************************************************/
  407. #define vlc_thread_join( P_THIS )                                           \
  408.     vlc_thread_join( VLC_OBJECT(P_THIS) )
  409.  
  410. #ifdef __cplusplus
  411. /**
  412.  * Helper C++ class to lock a mutex.
  413.  * The mutex is locked when the object is created, and unlocked when the object
  414.  * is destroyed.
  415.  */
  416. class vlc_mutex_locker
  417. {
  418.     private:
  419.         vlc_mutex_t *lock;
  420.     public:
  421.         vlc_mutex_locker (vlc_mutex_t *m) : lock (m)
  422.         {
  423.             vlc_mutex_lock (lock);
  424.         }
  425.  
  426.         ~vlc_mutex_locker (void)
  427.         {
  428.             vlc_mutex_unlock (lock);
  429.         }
  430. };
  431. #endif
  432.  
  433. enum {
  434.    VLC_XLIB_MUTEX,
  435.    /* Insert new entry HERE */
  436.    VLC_MAX_MUTEX
  437. };
  438.  
  439. VLC_EXPORT( void, vlc_global_mutex, ( unsigned, bool ) );
  440. #define vlc_global_lock( n ) vlc_global_mutex( n, true )
  441. #define vlc_global_unlock( n ) vlc_global_mutex( n, false )
  442.  
  443. #endif /* !_VLC_THREADS_H */
  444.